package cn.bonoon.kernel.annotations.services;

import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

import java.lang.annotation.Retention;
import java.lang.annotation.Target;

import cn.bonoon.kernel.support.entities.Persistable;

/**
 * 自动生成实现接口的类或部分抽象函数
 * 
 * <pre>
 * 在接口内的抽象函数中，可搭配使用{@link Select},{@link From},{@link Where},{@link AutoTransform} 4个注解实现查询
 * 使用方法：参考{@link TestAbstractService}
 * 
 * 函数参数：
 * 支持8种基本类型和11种对象类型(byte,short,int,long,float,double,char,boolean,Byte,Short,Integer,Long,Float,Double,Character,Boolean,String,Date,Object)
 * 
 * <table>
 * <tr><td>返回类型：</td></tr>
 * <tr><td>1.Persistable</td> <td>返回单个实体时使用  (e.g. RoleEntity)</td></tr>
 * <tr><td>2.Object</td> <td>返回自定义对象(e.g. PlaceDetail)，或返回一条记录的一个属性时使用，支持基本类型和对象类型  (e.g. Long)</td></tr>
 * <tr><td>3.Array</td> <td>返回一条记录的 N(N>1) 个属性时使用，支持基本类型和对象类型一维数组  (e.g. String[])</td></tr>
 * <tr><td>4.Collection</td> <td>返回自定义对象集合 (e.g. List<PlaceDetail>)，或返回多个实体或多个实体中的 N(N>=1) 个属性时使用 (e.g. List<RoleEntity>)</td></tr>
 * <tr><td>5.Page</td> <td>返回分页对象时使用，可以查找 N(N>=1) 个实体或一个实体中的 N(N>=1) 个属性，也可以转换为自定义对象</td></tr>
 * </table>
 * 
 * 查询规则（内部实现的逻辑）：
 * a)函数返回类型为 Persistable
 *   1.是否添加 {@link From} 注解 ? 2 : 3;
 *   2.查找 {@link From} 所定义的类
 *   3.返回类型是否与接口泛型实体(domainClass)相同或是它的父类 ? 4 : 5;
 *   4.查找接口泛型实体domainClass
 *   5.查找返回类型
 * b)函数返回类型为 Object
 *   0.是否添加 {@link AutoTransform} 注解 ? 3 : 1;
 *   1.是否添加 {@link From} 注解 ? 2 : 3;
 *   2.查找 {@link From} 所定义的类
 *   3.查找接口泛型实体 domainClass
 * c)函数返回类型为 Array
 *   1.是否添加 {@link From} 注解 ? 2 : 3;
 *   2.查找 {@link From} 所定义的类
 *   3.查找接口泛型实体 domainClass
 * d)函数返回类型为 Collection
 *   0.是否添加 {@link AutoTransform} 注解 ? 5 : 1;
 *   1.是否添加 {@link From} 注解 ? 2 : 3;
 *   2.查找 {@link From} 所定义的类
 *   3.函数返回的List<T>中，T是否是实体类型(实现Persistable) ? 4 : 5;
 *   4.T是否与接口泛型实体(domainClass)相同或是它的父类 ? 5 : 6;
 *   5.查找接口泛型实体domainClass
 *   6.查找T
 * e)函数返回类型为 Page
 *   0.是否添加 {@link AutoTransform} 注解 ? 3 : 1;
 *   1.是否指定 {@link From} ? 2 : 3;
 *   2.查找 {@link From} 所定义的类
 *   3.查找接口泛型实体domainClass
 * </pre>
 * 
 * @author ocean~
 */
@Target(TYPE)
@Retention(RUNTIME)
public @interface AutoImplements {

	/**
	 * 指定实体类(如：TestEntity.class)
	 */
	Class<? extends Persistable> entityClass();

	/**
	 * <pre>
	 * 指定父类，4个可选：
	 * {@link cn.bonoon.kernel.support.services.ServiceSupport ServiceSupport}
	 * {@link cn.bonoon.kernel.support.services.SearchSupport SearchSupport}
	 * {@link cn.bonoon.kernel.support.services.AbstractService AbstractService}
	 * {@link cn.bonoon.kernel.support.services.AbstractTreeService AbstractTreeService}
	 * </pre>
	 */
	Class<?> parentClass();

}
